#ifndef __WIZ_BNF_PARSER_HPP__SHANHAOBO_19800429__
#define __WIZ_BNF_PARSER_HPP__SHANHAOBO_19800429__

#include "../../Base/WizBase.hpp"

#include "../WizBNFMatch.hpp"

#include "./WizBNFParserImpl.hpp"

namespace Wiz
{
    namespace BNF
    {
        /// Pre declaration
        namespace Action
        {
            template<class DerivedT, class ActionT>
            class Type;
        }
        namespace Parser
        {
            namespace Category
            {
                struct Plain{};
                struct Binary       : Plain{};
                struct Unary        : Plain{};
                struct Action       : Unary{};
            } /// end of namespace Category

            template <typename ParserT, typename ScannerT>
            struct Result
            {
                typedef typename ::Wiz::TypeTraits::Remove::Reference<ParserT>::tType   tParser;
                typedef typename tParser::template Result<ScannerT>::tType              tType;
            };

            template <typename DerivedT>
            struct Type
            {
                typedef DerivedT                                    tEmbedded;
                typedef DerivedT                                    tDerived;
                typedef tDerived*                                   tDerivedPtr;
                typedef tDerived const*                             tDerivedConstPtr;
                typedef ::Wiz::BNF::Parser::Category::Plain         tCategory;

                template <typename ScannerT>
                struct Result
                {
                    typedef typename ::Wiz::BNF::Match::Result<
                        ScannerT,
                        ::Wiz::Null::Type
                    >::tType tType;
                };

                DerivedT& Derived()
                {
                    return *(static_cast<tDerivedPtr>(this));
                }

                DerivedT const& Derived() const
                {
                    return *(static_cast<tDerivedConstPtr>(this));
                }

                template <typename ActionT>
                ::Wiz::BNF::Action::Type<tDerived, ActionT> operator[](ActionT const& ActRef) const
                {
                    return ::Wiz::BNF::Action::Type<tDerived, ActionT>(Derived(), ActRef);
                }

                template <typename ScannerT>
                typename ::Wiz::BNF::Parser::Result<tDerived, ScannerT>::tType
                Parse(ScannerT const& Scan) const
                {
                    typedef typename ::Wiz::BNF::Parser::Result<tDerived, ScannerT>::tType tResult;
                    ScannerT::tIterator StartItr = Scan.m_Curr;
                    tResult Rslt = Derived().ParseImpl(Scan);
                    if (Rslt.NotValid())
                    {
                        /// Revert
                        Scan.m_Curr = StartItr;
                    }

                    return Rslt;
                }
            }; /// end of struct Type
        } /// end of namespace Parser
    } /// end of namespace BNF
} /// end of namespace Wiz

#endif /*__WIZ_BNF_PARSER_HPP__SHANHAOBO_19800429__*/
